#!/bin/bash

#-- Power of & --
# when & is used in the replacement-string, it replace it with whatever text matched the original-string or
# the regular expression.

# - enclose the employee id between '[' and ']', i.e. 101 -> [101]
sed 's/^[0-9][0-9][0-9]/[&]/g' ./test_employee.txt
echo -e '\n'

# - enclose the whole input line with '<' and '>'
sed 's/^.*/<&>/g' ./test_employee.txt
echo -e '\n'





#-- Substitution Grouping (single group) --
# grouping can be used in sed just like in a normal regular expression.
# a group is opend with '\(' back-slash with left parenthesis and closed with '\)' back-slash with right parenthesis

# matching group: in regular expression, we can use '\(' and '\)‘ to declar a matching group.
#                 it saves the matched characters for later use. such as, we can use \1 to referencing
#                 the first part of matched characters. we call this kind of behaviour "back-referencing"

# grouping can be used in combination with back-referencing.

# - single grouping
sed 's/\([^,]*\).*/\1/g' ./test_employee.txt
echo -e '\n'
# regexpr \([^,]*\) matches the string up to the 1st comma
# \1 in replacement-string replaces the first matched group.

# - display only the first field from /etc/passwd file
sed 's/\([^:]*\).*/\1/' /etc/passwd
echo -e '\n'

# - encloses the first letter in every word inside (), if the fist character is upper case
echo "The Geek Stuff and Tools" | sed 's/\(\b[A-Z]\)/\(\1\)/g'
echo -e '\n'
# * \b identify the english words, [A-Z] matching the first upper case character.
# * regexpr: \(\b[A-Z]\) matchs the frst upper case char of a word, save it for back-referencing
# * \(\1\) is in replacement-string, it makes the upper letter embraced by parenthesises. i.e. The -> (T)he

# - surrounding the id with '[]'
sed 's/\([0-9][0-9][0-9]\)/[\1]/' ./test_employee.txt
echo -e '\n'



#-- Multiple Grouping --
# in multi grouping , you can have multiple groups enclosed in multi "\(" and " \)".
# when you have multiple groups in the substitude regular expressioni, you can use "\n" (i.e. \1, \2)
# to specify the nth group.

# - get only 1st column and the 3rd column: 
sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\1, \3/g' ./test_employee.txt
echo -e '\n'

# - switch field1 with field2 
sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\2,\1,\3/g' ./test_employee.txt
echo -e '\n'




#-- Replacement String Flag --
# only GNU sed is avaliable.

# * \l: used in replacement-string part, it treats the caracter that immediately follow \l as lower case.
# * \L: used in replacement-string part, it treats the rest of caracters as lower case.

# - change John to JOHNNY
sed 's/John/JONNY/g' ./test_employee.txt
echo -e '\n'

# - change John to JOhNNY:
sed -n 's/John/JO\lHNNY/p' ./test_employee.txt # prints JOhNNY, H -> h
echo -e '\n'

# - change John to JOhnny:
sed -n 's/John/JO\LHNNY/p' ./test_employee.txt # prints JOhnny, HNNY -> hnny
echo -e '\n'

# * \u: used in replacement-string, like \l, but for upper case 
# * \U: used in replacement-string, like \L, but for upper case 

# - change John to joHnny: 
sed -n 's/John/jo\uhnny/p' ./test_employee.txt # prints joHnny, n -> N
echo -e '\n'

# * \E: used in conjunction with either \L or \U. stops the convertion initiated by \L or \U.
# - chagne John to JOHNNY BOT
sed -n 's/John/\UJohnny boy/p' ./test_employee.txt # prints JOHNNY BOY
echo -e '\n'

# - change John to JOHNNY Boy
sed -n 's/John/\UJohnny\E Boy/p' ./test_employee.txt # prints JOHNNY Boy, end upper-case replace before Boy

